{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": [],
      "mount_file_id": "1PjCGECqB37_TDD3kLHYl3IljlWxPNoXe",
      "authorship_tag": "ABX9TyNXz5GWZoO1Il0fH6PvILde",
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/onlyphantom/llm-python/blob/main/workshop/Generative_AI_Template_01.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "!pip install langchain\n",
        "!pip install langchain-groq\n",
        "\n",
        "import os\n",
        "import json\n",
        "import requests\n",
        "from langchain_core.tools import tool\n",
        "from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder\n",
        "from langchain_groq import ChatGroq\n",
        "from langchain.agents import create_tool_calling_agent, AgentExecutor\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "collapsed": true,
        "id": "i_SdqPeOZkH1",
        "outputId": "02804e14-8cc9-4d95-f799-72a722a3208a"
      },
      "execution_count": 5,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Requirement already satisfied: langchain in /usr/local/lib/python3.10/dist-packages (0.2.11)\n",
            "Requirement already satisfied: PyYAML>=5.3 in /usr/local/lib/python3.10/dist-packages (from langchain) (6.0.1)\n",
            "Requirement already satisfied: SQLAlchemy<3,>=1.4 in /usr/local/lib/python3.10/dist-packages (from langchain) (2.0.31)\n",
            "Requirement already satisfied: aiohttp<4.0.0,>=3.8.3 in /usr/local/lib/python3.10/dist-packages (from langchain) (3.9.5)\n",
            "Requirement already satisfied: async-timeout<5.0.0,>=4.0.0 in /usr/local/lib/python3.10/dist-packages (from langchain) (4.0.3)\n",
            "Requirement already satisfied: langchain-core<0.3.0,>=0.2.23 in /usr/local/lib/python3.10/dist-packages (from langchain) (0.2.24)\n",
            "Requirement already satisfied: langchain-text-splitters<0.3.0,>=0.2.0 in /usr/local/lib/python3.10/dist-packages (from langchain) (0.2.2)\n",
            "Requirement already satisfied: langsmith<0.2.0,>=0.1.17 in /usr/local/lib/python3.10/dist-packages (from langchain) (0.1.93)\n",
            "Requirement already satisfied: numpy<2,>=1 in /usr/local/lib/python3.10/dist-packages (from langchain) (1.26.4)\n",
            "Requirement already satisfied: pydantic<3,>=1 in /usr/local/lib/python3.10/dist-packages (from langchain) (2.8.2)\n",
            "Requirement already satisfied: requests<3,>=2 in /usr/local/lib/python3.10/dist-packages (from langchain) (2.31.0)\n",
            "Requirement already satisfied: tenacity!=8.4.0,<9.0.0,>=8.1.0 in /usr/local/lib/python3.10/dist-packages (from langchain) (8.5.0)\n",
            "Requirement already satisfied: aiosignal>=1.1.2 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.3.1)\n",
            "Requirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (23.2.0)\n",
            "Requirement already satisfied: frozenlist>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.4.1)\n",
            "Requirement already satisfied: multidict<7.0,>=4.5 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (6.0.5)\n",
            "Requirement already satisfied: yarl<2.0,>=1.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.9.4)\n",
            "Requirement already satisfied: jsonpatch<2.0,>=1.33 in /usr/local/lib/python3.10/dist-packages (from langchain-core<0.3.0,>=0.2.23->langchain) (1.33)\n",
            "Requirement already satisfied: packaging<25,>=23.2 in /usr/local/lib/python3.10/dist-packages (from langchain-core<0.3.0,>=0.2.23->langchain) (24.1)\n",
            "Requirement already satisfied: orjson<4.0.0,>=3.9.14 in /usr/local/lib/python3.10/dist-packages (from langsmith<0.2.0,>=0.1.17->langchain) (3.10.6)\n",
            "Requirement already satisfied: annotated-types>=0.4.0 in /usr/local/lib/python3.10/dist-packages (from pydantic<3,>=1->langchain) (0.7.0)\n",
            "Requirement already satisfied: pydantic-core==2.20.1 in /usr/local/lib/python3.10/dist-packages (from pydantic<3,>=1->langchain) (2.20.1)\n",
            "Requirement already satisfied: typing-extensions>=4.6.1 in /usr/local/lib/python3.10/dist-packages (from pydantic<3,>=1->langchain) (4.12.2)\n",
            "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2->langchain) (3.3.2)\n",
            "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2->langchain) (3.7)\n",
            "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2->langchain) (2.0.7)\n",
            "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2->langchain) (2024.7.4)\n",
            "Requirement already satisfied: greenlet!=0.4.17 in /usr/local/lib/python3.10/dist-packages (from SQLAlchemy<3,>=1.4->langchain) (3.0.3)\n",
            "Requirement already satisfied: jsonpointer>=1.9 in /usr/local/lib/python3.10/dist-packages (from jsonpatch<2.0,>=1.33->langchain-core<0.3.0,>=0.2.23->langchain) (3.0.0)\n",
            "Collecting langchain-groq\n",
            "  Downloading langchain_groq-0.1.8-py3-none-any.whl.metadata (2.9 kB)\n",
            "Collecting groq<1,>=0.4.1 (from langchain-groq)\n",
            "  Downloading groq-0.9.0-py3-none-any.whl.metadata (13 kB)\n",
            "Requirement already satisfied: langchain-core<0.3,>=0.2.24 in /usr/local/lib/python3.10/dist-packages (from langchain-groq) (0.2.24)\n",
            "Requirement already satisfied: anyio<5,>=3.5.0 in /usr/local/lib/python3.10/dist-packages (from groq<1,>=0.4.1->langchain-groq) (3.7.1)\n",
            "Requirement already satisfied: distro<2,>=1.7.0 in /usr/lib/python3/dist-packages (from groq<1,>=0.4.1->langchain-groq) (1.7.0)\n",
            "Collecting httpx<1,>=0.23.0 (from groq<1,>=0.4.1->langchain-groq)\n",
            "  Downloading httpx-0.27.0-py3-none-any.whl.metadata (7.2 kB)\n",
            "Requirement already satisfied: pydantic<3,>=1.9.0 in /usr/local/lib/python3.10/dist-packages (from groq<1,>=0.4.1->langchain-groq) (2.8.2)\n",
            "Requirement already satisfied: sniffio in /usr/local/lib/python3.10/dist-packages (from groq<1,>=0.4.1->langchain-groq) (1.3.1)\n",
            "Requirement already satisfied: typing-extensions<5,>=4.7 in /usr/local/lib/python3.10/dist-packages (from groq<1,>=0.4.1->langchain-groq) (4.12.2)\n",
            "Requirement already satisfied: PyYAML>=5.3 in /usr/local/lib/python3.10/dist-packages (from langchain-core<0.3,>=0.2.24->langchain-groq) (6.0.1)\n",
            "Requirement already satisfied: jsonpatch<2.0,>=1.33 in /usr/local/lib/python3.10/dist-packages (from langchain-core<0.3,>=0.2.24->langchain-groq) (1.33)\n",
            "Requirement already satisfied: langsmith<0.2.0,>=0.1.75 in /usr/local/lib/python3.10/dist-packages (from langchain-core<0.3,>=0.2.24->langchain-groq) (0.1.93)\n",
            "Requirement already satisfied: packaging<25,>=23.2 in /usr/local/lib/python3.10/dist-packages (from langchain-core<0.3,>=0.2.24->langchain-groq) (24.1)\n",
            "Requirement already satisfied: tenacity!=8.4.0,<9.0.0,>=8.1.0 in /usr/local/lib/python3.10/dist-packages (from langchain-core<0.3,>=0.2.24->langchain-groq) (8.5.0)\n",
            "Requirement already satisfied: idna>=2.8 in /usr/local/lib/python3.10/dist-packages (from anyio<5,>=3.5.0->groq<1,>=0.4.1->langchain-groq) (3.7)\n",
            "Requirement already satisfied: exceptiongroup in /usr/local/lib/python3.10/dist-packages (from anyio<5,>=3.5.0->groq<1,>=0.4.1->langchain-groq) (1.2.2)\n",
            "Requirement already satisfied: certifi in /usr/local/lib/python3.10/dist-packages (from httpx<1,>=0.23.0->groq<1,>=0.4.1->langchain-groq) (2024.7.4)\n",
            "Collecting httpcore==1.* (from httpx<1,>=0.23.0->groq<1,>=0.4.1->langchain-groq)\n",
            "  Downloading httpcore-1.0.5-py3-none-any.whl.metadata (20 kB)\n",
            "Collecting h11<0.15,>=0.13 (from httpcore==1.*->httpx<1,>=0.23.0->groq<1,>=0.4.1->langchain-groq)\n",
            "  Downloading h11-0.14.0-py3-none-any.whl.metadata (8.2 kB)\n",
            "Requirement already satisfied: jsonpointer>=1.9 in /usr/local/lib/python3.10/dist-packages (from jsonpatch<2.0,>=1.33->langchain-core<0.3,>=0.2.24->langchain-groq) (3.0.0)\n",
            "Requirement already satisfied: orjson<4.0.0,>=3.9.14 in /usr/local/lib/python3.10/dist-packages (from langsmith<0.2.0,>=0.1.75->langchain-core<0.3,>=0.2.24->langchain-groq) (3.10.6)\n",
            "Requirement already satisfied: requests<3,>=2 in /usr/local/lib/python3.10/dist-packages (from langsmith<0.2.0,>=0.1.75->langchain-core<0.3,>=0.2.24->langchain-groq) (2.31.0)\n",
            "Requirement already satisfied: annotated-types>=0.4.0 in /usr/local/lib/python3.10/dist-packages (from pydantic<3,>=1.9.0->groq<1,>=0.4.1->langchain-groq) (0.7.0)\n",
            "Requirement already satisfied: pydantic-core==2.20.1 in /usr/local/lib/python3.10/dist-packages (from pydantic<3,>=1.9.0->groq<1,>=0.4.1->langchain-groq) (2.20.1)\n",
            "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2->langsmith<0.2.0,>=0.1.75->langchain-core<0.3,>=0.2.24->langchain-groq) (3.3.2)\n",
            "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2->langsmith<0.2.0,>=0.1.75->langchain-core<0.3,>=0.2.24->langchain-groq) (2.0.7)\n",
            "Downloading langchain_groq-0.1.8-py3-none-any.whl (14 kB)\n",
            "Downloading groq-0.9.0-py3-none-any.whl (103 kB)\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m103.5/103.5 kB\u001b[0m \u001b[31m4.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25hDownloading httpx-0.27.0-py3-none-any.whl (75 kB)\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m75.6/75.6 kB\u001b[0m \u001b[31m5.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25hDownloading httpcore-1.0.5-py3-none-any.whl (77 kB)\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m77.9/77.9 kB\u001b[0m \u001b[31m5.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25hDownloading h11-0.14.0-py3-none-any.whl (58 kB)\n",
            "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.3/58.3 kB\u001b[0m \u001b[31m3.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
            "\u001b[?25hInstalling collected packages: h11, httpcore, httpx, groq, langchain-groq\n",
            "Successfully installed groq-0.9.0 h11-0.14.0 httpcore-1.0.5 httpx-0.27.0 langchain-groq-0.1.8\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "id": "l8hnoAwIU7s9"
      },
      "outputs": [],
      "source": [
        "from google.colab import userdata\n",
        "\n",
        "SECTORS_API_KEY = userdata.get('SECTORS_API_KEY')\n",
        "GROQ_API_KEY = userdata.get('GROQ_API_KEY')"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Warm up\n",
        "Here's a quick warm-up exercise. Below, we're using one of the [endpoints available at Sectors API](https://docs.sectors.app) to make our first HTTP request.  "
      ],
      "metadata": {
        "id": "vuLUMdjXaa-P"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import requests\n",
        "import pprint\n",
        "\n",
        "headers = {\n",
        "    \"Authorization\": SECTORS_API_KEY\n",
        "}\n",
        "\n",
        "\n",
        "def get_overview(stock:str, section:str) -> requests:\n",
        "    url = f\"https://api.sectors.app/v1/company/report/{stock}/?sections={section}\"\n",
        "    response = requests.get(url, headers=headers)\n",
        "    return response\n",
        "\n",
        "\n",
        "response = get_overview(\"BBRI\", \"financials\")\n",
        "pprint.pprint(response.json())"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "j9SUZx-2Zhi-",
        "outputId": "26b4de83-4d07-4df0-c428-cf7218293146"
      },
      "execution_count": 9,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "{'company_name': 'PT Bank Rakyat Indonesia (Persero) Tbk',\n",
            " 'financials': {'cash_flow_debt_ratio': 0.7816831005258889,\n",
            "                'dar_mrq': 0.0753361231980293,\n",
            "                'der_mrq': 0.501336568777284,\n",
            "                'historical_financials': [{'cash_and_equivalents': None,\n",
            "                                           'cash_only': None,\n",
            "                                           'current_liabilities': None,\n",
            "                                           'earnings': 32351133000000,\n",
            "                                           'earnings_before_tax': 41753694000000,\n",
            "                                           'fixed_assets': None,\n",
            "                                           'gross_profit': None,\n",
            "                                           'operating_pnl': 35523560000000,\n",
            "                                           'revenue': 98729001000000,\n",
            "                                           'tax': 9335208000000,\n",
            "                                           'total_assets': 1296898292000000,\n",
            "                                           'total_cash_and_due_from_banks': 166922967000000,\n",
            "                                           'total_debt': 119631712000000,\n",
            "                                           'total_equity': 185275331000000,\n",
            "                                           'total_liabilities': 1109714043000000,\n",
            "                                           'year': 2018},\n",
            "                                          {'cash_and_equivalents': None,\n",
            "                                           'cash_only': None,\n",
            "                                           'current_liabilities': None,\n",
            "                                           'earnings': 34372609000000,\n",
            "                                           'earnings_before_tax': 43364053000000,\n",
            "                                           'fixed_assets': None,\n",
            "                                           'gross_profit': None,\n",
            "                                           'operating_pnl': 36380061000000,\n",
            "                                           'revenue': 108387340000000,\n",
            "                                           'tax': 8950228000000,\n",
            "                                           'total_assets': 1416758840000000,\n",
            "                                           'total_cash_and_due_from_banks': 202104930000000,\n",
            "                                           'total_debt': 138880741000000,\n",
            "                                           'total_equity': 208784336000000,\n",
            "                                           'total_liabilities': 1207974504000000,\n",
            "                                           'year': 2019},\n",
            "                                          {'cash_and_equivalents': None,\n",
            "                                           'cash_only': None,\n",
            "                                           'current_liabilities': None,\n",
            "                                           'earnings': 18654753000000,\n",
            "                                           'earnings_before_tax': 29993406000000,\n",
            "                                           'fixed_assets': None,\n",
            "                                           'gross_profit': None,\n",
            "                                           'operating_pnl': 29520730000000,\n",
            "                                           'revenue': 130295121000000,\n",
            "                                           'tax': 8951971000000,\n",
            "                                           'total_assets': 1610065344000000,\n",
            "                                           'total_cash_and_due_from_banks': 139789887000000,\n",
            "                                           'total_debt': 195651325000000,\n",
            "                                           'total_equity': 229466882000000,\n",
            "                                           'total_liabilities': 1380598462000000,\n",
            "                                           'year': 2020},\n",
            "                                          {'cash_and_equivalents': None,\n",
            "                                           'cash_only': None,\n",
            "                                           'current_liabilities': None,\n",
            "                                           'earnings': 31066592000000,\n",
            "                                           'earnings_before_tax': 40992065000000,\n",
            "                                           'fixed_assets': None,\n",
            "                                           'gross_profit': None,\n",
            "                                           'operating_pnl': 40509273000000,\n",
            "                                           'revenue': 153174192000000,\n",
            "                                           'tax': 7835608000000,\n",
            "                                           'total_assets': 1678097734000000,\n",
            "                                           'total_cash_and_due_from_banks': 131474664000000,\n",
            "                                           'total_debt': 167004561000000,\n",
            "                                           'total_equity': 291786804000000,\n",
            "                                           'total_liabilities': 1386310930000000,\n",
            "                                           'year': 2021},\n",
            "                                          {'cash_and_equivalents': None,\n",
            "                                           'cash_only': None,\n",
            "                                           'current_liabilities': None,\n",
            "                                           'earnings': 51170312000000,\n",
            "                                           'earnings_before_tax': 64596701000000,\n",
            "                                           'fixed_assets': None,\n",
            "                                           'gross_profit': None,\n",
            "                                           'operating_pnl': 64160242000000,\n",
            "                                           'revenue': 168223027000000,\n",
            "                                           'tax': 13188494000000,\n",
            "                                           'total_assets': 1865639010000000,\n",
            "                                           'total_cash_and_due_from_banks': 233531261000000,\n",
            "                                           'total_debt': 162817088000000,\n",
            "                                           'total_equity': 303395317000000,\n",
            "                                           'total_liabilities': 1562243693000000,\n",
            "                                           'year': 2022},\n",
            "                                          {'cash_and_equivalents': None,\n",
            "                                           'cash_only': 31603784000000,\n",
            "                                           'current_liabilities': None,\n",
            "                                           'earnings': 60099863000000,\n",
            "                                           'earnings_before_tax': 76429712000000,\n",
            "                                           'fixed_assets': None,\n",
            "                                           'gross_profit': None,\n",
            "                                           'operating_pnl': None,\n",
            "                                           'revenue': 166475993000000,\n",
            "                                           'tax': 16004664000000,\n",
            "                                           'total_assets': 1965007030000000,\n",
            "                                           'total_cash_and_due_from_banks': 192435481000000,\n",
            "                                           'total_debt': 149849160000000,\n",
            "                                           'total_equity': 316472142000000,\n",
            "                                           'total_liabilities': 1648534888000000,\n",
            "                                           'year': 2023}],\n",
            "                'interest_coverage_ratio': None,\n",
            "                'net_profit_margin': 0.3346784329162555,\n",
            "                'roa_ttm': 0.03010350976405042,\n",
            "                'roe_ttm': 0.2003287354406536,\n",
            "                'yoy_quarter_earnings_growth': 0.322241679949,\n",
            "                'yoy_quarter_revenue_growth': 0.082337052527442},\n",
            " 'symbol': 'BBRI.JK'}\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "ENAEwetYaHkO"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Self Assessment\n",
        "\n",
        "Complete **any one of the following two** exercises to get a certificate.\n",
        "\n"
      ],
      "metadata": {
        "id": "TzeEj1zJb646"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Exercise 1\n",
        "Modify and improve the orchestration script below. Here are some things you might want to try:\n",
        "\n",
        "\n",
        "\n",
        "*   Sam says [the `llama3-groq-70b-8192-tool-use-preview`](https://console.groq.com/docs/models) is a superior model specialized in tool use and function calling tasks. It might be worth swapping in that model.\n",
        "*   Could the system prompt be improved?\n",
        "*   Could the docstring in that tool be improved?\n",
        "\n"
      ],
      "metadata": {
        "id": "XgnNBwUzxuIX"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "from langchain_core.tools import tool\n",
        "\n",
        "def retrieve_from_endpoint(url: str) -> dict:\n",
        "    headers = {\"Authorization\": SECTORS_API_KEY}\n",
        "\n",
        "    try:\n",
        "        response = requests.get(url, headers=headers)\n",
        "        response.raise_for_status()\n",
        "        data = response.json()\n",
        "    except requests.exceptions.HTTPError as err:\n",
        "        raise SystemExit(err)\n",
        "    return json.dumps(data)\n",
        "\n",
        "\n",
        "@tool\n",
        "def get_top_companies_by_tx_volume(\n",
        "    start_date: str, end_date: str, top_n: int = 5\n",
        ") -> str:\n",
        "    \"\"\"\n",
        "    Get top companies by transaction volume\n",
        "    \"\"\"\n",
        "    url = f\"https://api.sectors.app/v1/most-traded/?start={start_date}&end={end_date}&n_stock={top_n}\"\n",
        "\n",
        "    return retrieve_from_endpoint(url)\n",
        "\n",
        "tools = [get_top_companies_by_tx_volume]\n",
        "llm = ChatGroq(\n",
        "    temperature=0,\n",
        "    model_name=\"llama3-70b-8192\",\n",
        "    groq_api_key=GROQ_API_KEY,\n",
        ")\n",
        "\n",
        "prompt = ChatPromptTemplate.from_messages(\n",
        "    [\n",
        "        (\n",
        "            \"system\",\n",
        "            \"Answer the following queries, as if you are a financial robo-advisor.\",\n",
        "        ),\n",
        "        (\"human\", \"{input}\"),\n",
        "        # msg containing previous agent tool invocations and corresponding tool outputs\n",
        "        MessagesPlaceholder(\"agent_scratchpad\"),\n",
        "    ]\n",
        ")\n",
        "agent = create_tool_calling_agent(llm, tools, prompt)\n",
        "agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)\n",
        "\n",
        "query = \"What are the top 3 companies by transaction volume over the last 7 days?\"\n",
        "result = agent_executor.invoke({\"input\": query})\n",
        "print(\"Answer:\", \"\\n\", result[\"output\"], \"\\n\\n======\\n\\n\")\n",
        "\n"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 504
        },
        "collapsed": true,
        "id": "vB4AL8uogxcn",
        "outputId": "1a59ca22-279e-430b-e909-ac36c3acb625"
      },
      "execution_count": 13,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "\n",
            "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
            "\u001b[32;1m\u001b[1;3m\n",
            "Invoking: `get_top_companies_by_tx_volume` with `{'start_date': '7 days ago', 'end_date': 'today', 'top_n': 3}`\n",
            "\n",
            "\n",
            "\u001b[0m"
          ]
        },
        {
          "output_type": "error",
          "ename": "HTTPError",
          "evalue": "400 Client Error: Bad Request for url: https://api.sectors.app/v1/most-traded/?start=7%20days%20ago&end=today&n_stock=3",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mHTTPError\u001b[0m                                 Traceback (most recent call last)",
            "\u001b[0;32m<ipython-input-13-6ef0cbee8e9b>\u001b[0m in \u001b[0;36m<cell line: 48>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     46\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     47\u001b[0m \u001b[0mquery\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"What are the top 3 companies by transaction volume over the last 7 days?\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 48\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0magent_executor\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minvoke\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0;34m\"input\"\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mquery\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     49\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Answer:\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"\\n\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"output\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"\\n\\n======\\n\\n\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     50\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/langchain/chains/base.py\u001b[0m in \u001b[0;36minvoke\u001b[0;34m(self, input, config, **kwargs)\u001b[0m\n\u001b[1;32m    164\u001b[0m         \u001b[0;32mexcept\u001b[0m \u001b[0mBaseException\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    165\u001b[0m             \u001b[0mrun_manager\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mon_chain_error\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0me\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 166\u001b[0;31m             \u001b[0;32mraise\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    167\u001b[0m         \u001b[0mrun_manager\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mon_chain_end\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0moutputs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    168\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/langchain/chains/base.py\u001b[0m in \u001b[0;36minvoke\u001b[0;34m(self, input, config, **kwargs)\u001b[0m\n\u001b[1;32m    154\u001b[0m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_validate_inputs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minputs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    155\u001b[0m             outputs = (\n\u001b[0;32m--> 156\u001b[0;31m                 \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minputs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrun_manager\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mrun_manager\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    157\u001b[0m                 \u001b[0;32mif\u001b[0m \u001b[0mnew_arg_supported\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    158\u001b[0m                 \u001b[0;32melse\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minputs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/langchain/agents/agent.py\u001b[0m in \u001b[0;36m_call\u001b[0;34m(self, inputs, run_manager)\u001b[0m\n\u001b[1;32m   1610\u001b[0m         \u001b[0;31m# We now enter the agent loop (until it returns something).\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1611\u001b[0m         \u001b[0;32mwhile\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_should_continue\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0miterations\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtime_elapsed\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1612\u001b[0;31m             next_step_output = self._take_next_step(\n\u001b[0m\u001b[1;32m   1613\u001b[0m                 \u001b[0mname_to_tool_map\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1614\u001b[0m                 \u001b[0mcolor_mapping\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/langchain/agents/agent.py\u001b[0m in \u001b[0;36m_take_next_step\u001b[0;34m(self, name_to_tool_map, color_mapping, inputs, intermediate_steps, run_manager)\u001b[0m\n\u001b[1;32m   1316\u001b[0m     ) -> Union[AgentFinish, List[Tuple[AgentAction, str]]]:\n\u001b[1;32m   1317\u001b[0m         return self._consume_next_step(\n\u001b[0;32m-> 1318\u001b[0;31m             [\n\u001b[0m\u001b[1;32m   1319\u001b[0m                 \u001b[0ma\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1320\u001b[0m                 for a in self._iter_next_step(\n",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/langchain/agents/agent.py\u001b[0m in \u001b[0;36m<listcomp>\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m   1316\u001b[0m     ) -> Union[AgentFinish, List[Tuple[AgentAction, str]]]:\n\u001b[1;32m   1317\u001b[0m         return self._consume_next_step(\n\u001b[0;32m-> 1318\u001b[0;31m             [\n\u001b[0m\u001b[1;32m   1319\u001b[0m                 \u001b[0ma\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1320\u001b[0m                 for a in self._iter_next_step(\n",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/langchain/agents/agent.py\u001b[0m in \u001b[0;36m_iter_next_step\u001b[0;34m(self, name_to_tool_map, color_mapping, inputs, intermediate_steps, run_manager)\u001b[0m\n\u001b[1;32m   1401\u001b[0m             \u001b[0;32myield\u001b[0m \u001b[0magent_action\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1402\u001b[0m         \u001b[0;32mfor\u001b[0m \u001b[0magent_action\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mactions\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1403\u001b[0;31m             yield self._perform_agent_action(\n\u001b[0m\u001b[1;32m   1404\u001b[0m                 \u001b[0mname_to_tool_map\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolor_mapping\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0magent_action\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrun_manager\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1405\u001b[0m             )\n",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/langchain/agents/agent.py\u001b[0m in \u001b[0;36m_perform_agent_action\u001b[0;34m(self, name_to_tool_map, color_mapping, agent_action, run_manager)\u001b[0m\n\u001b[1;32m   1423\u001b[0m                 \u001b[0mtool_run_kwargs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"llm_prefix\"\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1424\u001b[0m             \u001b[0;31m# We then call the tool on the tool input to get an observation\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1425\u001b[0;31m             observation = tool.run(\n\u001b[0m\u001b[1;32m   1426\u001b[0m                 \u001b[0magent_action\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtool_input\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1427\u001b[0m                 \u001b[0mverbose\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mverbose\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/langchain_core/tools.py\u001b[0m in \u001b[0;36mrun\u001b[0;34m(self, tool_input, verbose, start_color, color, callbacks, tags, metadata, run_name, run_id, config, tool_call_id, **kwargs)\u001b[0m\n\u001b[1;32m    633\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0merror_to_raise\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    634\u001b[0m             \u001b[0mrun_manager\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mon_tool_error\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merror_to_raise\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 635\u001b[0;31m             \u001b[0;32mraise\u001b[0m \u001b[0merror_to_raise\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    636\u001b[0m         \u001b[0moutput\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_format_output\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcontent\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0martifact\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtool_call_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    637\u001b[0m         \u001b[0mrun_manager\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mon_tool_end\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0moutput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolor\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mcolor\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/langchain_core/tools.py\u001b[0m in \u001b[0;36mrun\u001b[0;34m(self, tool_input, verbose, start_color, color, callbacks, tags, metadata, run_name, run_id, config, tool_call_id, **kwargs)\u001b[0m\n\u001b[1;32m    606\u001b[0m             \u001b[0;32mif\u001b[0m \u001b[0mconfig_param\u001b[0m \u001b[0;34m:=\u001b[0m \u001b[0m_get_runnable_config_param\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_run\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    607\u001b[0m                 \u001b[0mtool_kwargs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mconfig_param\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mconfig\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 608\u001b[0;31m             \u001b[0mresponse\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcontext\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_run\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mtool_args\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mtool_kwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    609\u001b[0m             \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mresponse_format\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m\"content_and_artifact\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    610\u001b[0m                 \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresponse\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtuple\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresponse\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/langchain_core/tools.py\u001b[0m in \u001b[0;36m_run\u001b[0;34m(self, config, run_manager, *args, **kwargs)\u001b[0m\n\u001b[1;32m    943\u001b[0m             \u001b[0;32mif\u001b[0m \u001b[0mconfig_param\u001b[0m \u001b[0;34m:=\u001b[0m \u001b[0m_get_runnable_config_param\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    944\u001b[0m                 \u001b[0mkwargs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mconfig_param\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mconfig\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 945\u001b[0;31m             \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    946\u001b[0m         \u001b[0;32mraise\u001b[0m \u001b[0mNotImplementedError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"StructuredTool does not support sync invocation.\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    947\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m<ipython-input-13-6ef0cbee8e9b>\u001b[0m in \u001b[0;36mget_top_companies_by_tx_volume\u001b[0;34m(start_date, end_date, top_n)\u001b[0m\n\u001b[1;32m     22\u001b[0m     \u001b[0murl\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34mf\"https://api.sectors.app/v1/most-traded/?start={start_date}&end={end_date}&n_stock={top_n}\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     23\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 24\u001b[0;31m     \u001b[0;32mreturn\u001b[0m \u001b[0mretrieve_from_endpoint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0murl\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     25\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     26\u001b[0m \u001b[0mtools\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mget_top_companies_by_tx_volume\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m<ipython-input-13-6ef0cbee8e9b>\u001b[0m in \u001b[0;36mretrieve_from_endpoint\u001b[0;34m(url)\u001b[0m\n\u001b[1;32m      9\u001b[0m         \u001b[0mdata\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mresponse\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjson\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     10\u001b[0m     \u001b[0;32mexcept\u001b[0m \u001b[0mrequests\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexceptions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mHTTPError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 11\u001b[0;31m         \u001b[0;32mraise\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     12\u001b[0m     \u001b[0;32mreturn\u001b[0m \u001b[0mjson\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdumps\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     13\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m<ipython-input-13-6ef0cbee8e9b>\u001b[0m in \u001b[0;36mretrieve_from_endpoint\u001b[0;34m(url)\u001b[0m\n\u001b[1;32m      6\u001b[0m     \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      7\u001b[0m         \u001b[0mresponse\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrequests\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0murl\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mheaders\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mheaders\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m         \u001b[0mresponse\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mraise_for_status\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      9\u001b[0m         \u001b[0mdata\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mresponse\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjson\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     10\u001b[0m     \u001b[0;32mexcept\u001b[0m \u001b[0mrequests\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexceptions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mHTTPError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.10/dist-packages/requests/models.py\u001b[0m in \u001b[0;36mraise_for_status\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m   1019\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1020\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mhttp_error_msg\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1021\u001b[0;31m             \u001b[0;32mraise\u001b[0m \u001b[0mHTTPError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhttp_error_msg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mresponse\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1022\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1023\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0mclose\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;31mHTTPError\u001b[0m: 400 Client Error: Bad Request for url: https://api.sectors.app/v1/most-traded/?start=7%20days%20ago&end=today&n_stock=3"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "If you'd like another level of challenge, try and apply your tool-calling LLM model on the following, arguably more challenging, queries.\n",
        "\n",
        "You need to successfully execute this exercise with these 3 queries returning correct results to be considered successful at this challenge!"
      ],
      "metadata": {
        "id": "aMeT2m5EMJM8"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "queries = [\n",
        "    \"What are the top 5 companies by transaction volume on the first of this month?\",\n",
        "    \"What are the most traded stock yesterday?\"\n",
        "    \"What are the top 7 most traded stocks between 6th June to 10th June this year?\"\n",
        "]\n",
        "\n",
        "for query in queries:\n",
        "    print(\"Question:\", query)\n",
        "    result = agent_executor.invoke({\"input\": query})\n",
        "    print(\"Answer:\", \"\\n\", result[\"output\"], \"\\n\\n======\\n\\n\")"
      ],
      "metadata": {
        "id": "TWLSMUJP0BjH"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Exercise 2\n",
        "\n",
        "Our users have been using our tool and having a lot of success with it. It is now time to take it one step further: by collecting user's feedback!\n",
        "\n",
        "Here are the sample queries that performed sub-optimally according to user feedback:\n",
        "\n",
        "\n",
        "*   What is the performance of GOTO (symbol: GOTO) since its IPO listing?\n",
        "*   If i had invested into GOTO vs BREN on their respective IPO listing date, which one would have given me a better return over a 90 day horizon?\"\n",
        "\n",
        "Clearly, it's time to expand the tools that our language model has access to. For the second exercise, you'd be implementing **an additional** tool directly into the orchestrator to give your financial AI model a direct pathway to answering questions relating to stock performance since their listing date.\n",
        "\n",
        "\n",
        "> You may have to [refer to Sectors API Documentation](https://docs.sectors.app) for a list of endpoints and pick the one most suitable for the job.\n",
        "\n",
        "To help you get started, I've also added two new tools. Use them as a base reference! If you proceed to run the exercise without adding the right tool(s), `query_4` and `query_5` is most likely going to fail or cause the LLM to answer incorrectly."
      ],
      "metadata": {
        "id": "Ih2yJHQyWZkg"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "@tool\n",
        "def get_company_overview(stock: str) -> str:\n",
        "    \"\"\"\n",
        "    Get company overview\n",
        "    \"\"\"\n",
        "    url = f\"https://api.sectors.app/v1/company/report/{stock}/?sections=overview\"\n",
        "\n",
        "    return retrieve_from_endpoint(url)\n",
        "\n",
        "\n",
        "@tool\n",
        "def get_daily_tx(stock: str, start_date: str, end_date: str) -> str:\n",
        "    \"\"\"\n",
        "    Get daily transaction for a stock\n",
        "    \"\"\"\n",
        "    url = f\"https://api.sectors.app/v1/daily/{stock}/?start={start_date}&end={end_date}\"\n",
        "\n",
        "    return retrieve_from_endpoint(url)\n",
        "\n",
        "\n",
        "tools = [\n",
        "    get_company_overview,\n",
        "    # we created this in the earlier code chunk under Exercise 1\n",
        "    # (so make sure you've run that cell),\n",
        "    get_top_companies_by_tx_volume,\n",
        "    get_daily_tx,\n",
        "]\n",
        "\n",
        "query_1 = \"What are the top 3 companies by transaction volume over the last 7 days?\"\n",
        "query_2 = \"Based on the closing prices of BBCA between 1st and 30th of June 2024, are we seeing an uptrend or downtrend? Try to explain why.\"\n",
        "query_3 = \"What is the company with the largest market cap between BBCA and BREN? For said company, retrieve the email, phone number, listing date and website for further research.\"\n",
        "query_4 = \"What is the performance of GOTO (sym bol: GOTO) since its IPO listing?\"\n",
        "query_5 = \"If i had invested into GOTO vs BREN on their respective IPO listing date, which one would have given me a better return over a 90 day horizon?\"\n",
        "\n",
        "queries = [query_1, query_2, query_3, query_4, query_5]\n",
        "\n",
        "llm = ChatGroq(\n",
        "    temperature=0,\n",
        "    model_name=\"llama3-70b-8192\",\n",
        "    groq_api_key=GROQ_API_KEY,\n",
        ")\n",
        "\n",
        "prompt = ChatPromptTemplate.from_messages(\n",
        "    [\n",
        "        (\n",
        "            \"system\",\n",
        "            \"Answer the following queries, as if you are a financial robo-advisor.\",\n",
        "        ),\n",
        "        (\"human\", \"{input}\"),\n",
        "        # msg containing previous agent tool invocations and corresponding tool outputs\n",
        "        MessagesPlaceholder(\"agent_scratchpad\"),\n",
        "    ]\n",
        ")\n",
        "\n",
        "for query in queries:\n",
        "    print(\"Question:\", query)\n",
        "    result = agent_executor.invoke({\"input\": query})\n",
        "    print(\"Answer:\", \"\\n\", result[\"output\"], \"\\n\\n======\\n\\n\")"
      ],
      "metadata": {
        "id": "gphRx4bEXvID"
      },
      "execution_count": null,
      "outputs": []
    }
  ]
}